package com.ace.log.printer

import android.util.Log
import com.ace.log.LogLevel
import com.ace.log.decorator.IDecorator
import com.ace.log.decorator.SimpleDecorator
import com.ace.log.file.FileBuilder
import com.ace.log.file.FileWriter
import com.ace.log.file.LogItem
import com.ace.log.file.clean.ICleanStrategy
import com.ace.log.file.clean.NeverCleanStrategy
import com.ace.log.file.name.DateFileNameGenerator
import com.ace.log.file.name.IFileNameGenerator
import com.ace.log.scope.ioScope
import com.ace.log.utils.now

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.launch
import java.io.File


class FilePrinter(builder: FileBuilder) : IPrinter {
    override val decorator: IDecorator
    private val channel = Channel<LogItem>()
    private val folderPath: String
    private val fileNameGenerator: IFileNameGenerator
    private val cleanStrategy: ICleanStrategy
    private val writer: FileWriter

    init {
        ioScope().launch {
            channel.consumeEach {
                doWrite(it)
            }
        }
        decorator = builder.decorator ?: SimpleDecorator
        folderPath = builder.folderPath ?: "/sdcard/logs/"
        fileNameGenerator = builder.fileNameGenerator ?: DateFileNameGenerator()
        cleanStrategy = builder.cleanStrategy ?: NeverCleanStrategy()
        writer = FileWriter(folderPath)
    }

    override fun printLog(logLevel: LogLevel, tag: String, msg: String) {
        ioScope().launch {
            channel.send(LogItem(now(), logLevel, tag, msg))
        }
    }

    private fun doWrite(logItem: LogItem) {
        val lastFileName = writer.lastFileName
        if (lastFileName == null || fileNameGenerator.isFileNameChangeable()) {
            //新文件名
            val newFileName = fileNameGenerator.generateFileName(
                logItem.level.value,
                logItem.tag,
                System.currentTimeMillis(),
                lastFileName ?: ""
            )
            //删除旧文件创建新文件
            if (newFileName != lastFileName) {
                if (writer.isOpened) {
                    writer.close()
                }
                //旧文件清除策略
                cleanLogFilesIfNecessary()
                //创建并打开新文件
                if (!writer.open(newFileName)) {
                    return
                }
            }
        }
        //追加日志
        writer.appendLog(logItem.toString())
    }

    private fun cleanLogFilesIfNecessary() {
        File(folderPath).listFiles()?.forEach {
            if (cleanStrategy.shouldClean(it))
                it.delete()
        }
    }
}

